package com.shujia

object Code40Implicit {
  def main(args: Array[String]): Unit = {
    /**
     * 隐式转换：
     *    隐式转换是对应于显示转换
     *
     *    转换有三种类型：
     *      ① 隐式转换函数
     *          该方式可以使用 implicit 关键字修饰函数，修饰函数后，满足该函数的调用时，就会自动对类型进行转换
     *          注意：
     *             ① 该方式一般函数中只给定一个参数，并且有一个返回值
     *             ② 隐式转换函数在class中不能被直接调用
     *      ② 隐式转换类
     *          在类的前面，添加 implicit 关键字进行修饰，同时在类的主构造其中填写对应的传入参数
     *            之后传入参数类型的对象中就包含了 当前类中的相关函数 相当于特质
     *            注意： 隐式转换类需要在 object中进行定义
     *
     *      ③ 隐式转换变量
     *          在函数定义时，将参数列表中的参数使用 implicit 进行标记，之后再对 同类型的变量进行使用 implicit
     *          标记，那么在函数调用时，就不需要进行手动传参
     *
     */

    val stu =  ImpStu("黄小敏", 18, "大数据")
    // 显示转换
//    val teacher: ImpTeacher = stuChangeTeacher(stu)


    teach(stu)  // 调用了隐式转换 相当于 teach(impStuChangeTeacher(stu))

//    var str:String = "10"
//    println(useInt(str))


  }

  def teach(teacher: ImpTeacher): Unit = {

    println(s"${teacher.name}正在教授${teacher.teach},今年${teacher.age}了")
  }


  def stuChangeTeacher(stu:ImpStu): ImpTeacher = {
    ImpTeacher(stu.name,stu.age,stu.learn)
  }

  implicit def impStuChangeTeacher(stu: ImpStu): ImpTeacher = {
    ImpTeacher(stu.name, stu.age, stu.learn)
  }

  // 不规范
//  implicit def impStuChangeTeacher2(stu: ImpStu, stu2: ImpStu): ImpTeacher = {
//    ImpTeacher(stu.name, stu.age, stu.learn)
//    ImpTeacher(stu2.name, stu2.age, stu2.learn)
//  }

//  implicit def changeStr(string: String): Int = {
//    string.toInt
//  }
//
//  def useInt(int: Int): Unit = {
//    println(int * 10)
//  }

}


case class ImpStu(name: String, age: Int, learn: String)

case class ImpTeacher(name: String, age: Int, teach: String)


